using System;
using System.Collections.Generic;
using System.Windows.Forms;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.Loaders;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using DialogResult=Habanero.Faces.Base.DialogResult;
using MessageBoxButtons=Habanero.Faces.Base.MessageBoxButtons;
using MessageBoxIcon=Habanero.Faces.Base.MessageBoxIcon;

namespace FireStarterModeller.UI.ViewEditor
{
    public class UIViewSelectorControl : UserControlWin, IUIViewSelectorControl
    {
        private readonly IControlFactory _controlFactory;
        private readonly IDMToClassDefsXmlConverter _converter;
        private BusinessObjectCollection<UIView> _uiViews;
        public event EventHandler<BOEventArgs<UIView>> UIViewSelected;
        public event EventHandler<StringEventArgs> XMLCreatedToInsert;

        public IBOComboBoxSelector UIViewComboBox { get; private set; }

        public UIViewSelectorControl(IControlFactory controlFactory, IDMToClassDefsXmlConverter converter)
        {
            _controlFactory = controlFactory;
            _converter = converter;
            UIViewComboBox = _controlFactory.CreateComboBoxSelector();

            this.Padding = new Padding(5);

            FlowLayoutManager groupBoxLayoutManager = new FlowLayoutManager(this, _controlFactory);

            groupBoxLayoutManager.AddControl(_controlFactory.CreateLabel("Select UI Definition by name:"));
            groupBoxLayoutManager.AddControl(UIViewComboBox);
            CreateNewButton = _controlFactory.CreateButton("Create New", (sender,args) => CreateNewUIView());
            groupBoxLayoutManager.AddControl(CreateNewButton);
            IButton button = _controlFactory.CreateButton("Create New with Wizard", (sender, args) => CreateNewUIViewWithWizard());
            groupBoxLayoutManager.AddControl(button);
            DeleteButton = _controlFactory.CreateButton("Delete", (sender,args) => DeleteUIView());
            groupBoxLayoutManager.AddControl(DeleteButton);
            AddElementButton = _controlFactory.CreateButton("Add Element", (sender, args) => AddElement());
            groupBoxLayoutManager.AddControl(AddElementButton);
            this.Height = UIViewComboBox.Height + 5 * 2;

            UIViewComboBox.SelectedValueChanged += (sender, args) => FireUIViewSelected();
        }

        private void DeleteUIView()
        {
            UIView selectedUIView = SelectedUIView;
            if (selectedUIView != null)
            {
                if (_controlFactory.ShowMessageBox(
                    "Are you sure you want to delete this UI View?", 
                    "Confirm Delete", 
                    MessageBoxButtons.YesNo, 
                    MessageBoxIcon.Stop) == DialogResult.No)
                    return;
                selectedUIView.MarkForDelete();
                selectedUIView.Save();
                this.SelectedUIView = this.UIViews.Count > 0 ? this.UIViews[0] : null;
            }
        }

        private void CreateNewUIView() {
            UIView selectedUIView = SelectedUIView;
            UIView uiView;
            if (selectedUIView != null)
            {
                string xml = _converter.ConvertToXml(selectedUIView);
                XmlUILoader uiLoader = new XmlUILoader(new DtdLoader(), new FMDefClassFactory((DMSolution) selectedUIView.Class.Solution));
                uiView = (UIView)uiLoader.LoadUIDef(xml);
                UIViews.Add(uiView);
            } else
            {
                uiView = UIViews.CreateBusinessObject();
            }
            uiView.ViewName = "NewView";
            uiView.ViewName = uiView.Class.GetUniqueViewNameWithSuffix(uiView.ViewName);
            this.SelectedUIView = uiView;
        }

        private void FireUIViewSelected() { 
            if (UIViewSelected !=null)
            {
                UIViewSelected(this, new BOEventArgs<UIView>(SelectedUIView));
            }
        }

        private void AddElement()
        {
            IUIViewAddElementForm addElementForm = new UIViewAddElementForm(_controlFactory, _converter);
            addElementForm.ShowDialog();
            if (!string.IsNullOrEmpty(addElementForm.XMLToInsert))
            {
                XMLCreatedToInsert.BeginInvoke(this, new StringEventArgs(addElementForm.XMLToInsert), null, null);
            }
        }

        public BusinessObjectCollection<UIView> UIViews
        {
            get { return _uiViews; }
            set
            {
                _uiViews = value;
                UIViewComboBox.BusinessObjectCollection = _uiViews;
            }
        }

        public UIView SelectedUIView 
        { 
            get { return UIViewComboBox.SelectedValue as UIView; }
            set { UIViewComboBox.SelectedValue = value; 
            FireUIViewSelected();}
        }

        public IButton CreateNewButton { get; private set; }
        public IButton DeleteButton { get; private set; }
        public IButton AddElementButton { get; private set; }

        //TODO Mark 17 Dec 2009: This needs to be tested (It was copied and added from the old code in the DMClassEditorControl for use in a production project)
        private void CreateNewUIViewWithWizard()
        {
            DMClass dmClass = GetDMClass();
            if (dmClass == null) return;
            var wizardController = new CreateViewWizardController
            {
                Solution = (DMSolution) dmClass.Solution,
                Class = dmClass
            };
            IWizardForm wizardForm = _controlFactory.CreateWizardForm(wizardController);
            wizardForm.Text = "Select Properties for the Grid";
            wizardForm.Height = 600;
            wizardForm.Width = 620;
            if (wizardForm.ShowDialog() == DialogResult.OK)
            {
                this.SelectedUIView = wizardController.UIGrid.UIView;
            }
        }

        private DMClass GetDMClass()
        {
            UIView uiView = UIViews.CreateBusinessObject();
            DMClass dmClass = uiView.Class;
            uiView.MarkForDelete();
            uiView.Save();
            return dmClass;
        }
    }
}